/*
 *  Filename:      meos_sched.c
 *  Author:         Erick Huang<erickhuang1989@gmail.com>
 *  Revised:        2014-12-16
 *  Description:   
 *
 *  Copyright (c) Erick Huang. All rights reserved.
 */
#include "meos_api.h"


// Index of active task
static uint8 activeTaskID = TASK_NO_TASK;


/*********************************************************************
 * @fn      meos_init_system
 *
 * @brief   This function initializes the "task" system by creating the
 *                tasks defined in the task table (meos_tasks.h).
 *
 * @param   void
 *
 * @return  SUCCESS
 */
Status_t meos_init_system( void )
{
	// Initialize the Memory Allocation System
  	meos_mem_init();

	// Initialize the message queue
	meos_msg_init();

	// Initialize the timers
  	meos_timer_init();

  	// Initialize the Power Management System
  	meos_pwrmgr_init();
	
	// Initialize the system tasks.
  	meos_init_tasks();

  	return SUCCESS;
}

/*********************************************************************
 * @fn      meos_start_system
 *
 * @brief   This function is the main loop function of the task system . 
 *             This Function doesn't return.
 *
 * @param   void
 *
 * @return  none
 */
void meos_start_system( void )
{
  	for(;;)  // Forever Loop
  	{
    	meos_run_system();
  	}
}

/*********************************************************************
 * @fn      meos_run_system
 *
 * @brief
 *
 *   This function will make one pass through the MEOS taskEvents table
 *   and call the task_event_processor() function for the first task that
 *   is found with at least one event pending. If there are no pending
 *   events (all tasks), this function puts the processor into Sleep.
 *
 * @param   void
 *
 * @return  none
 */
void meos_run_system( void )
{
  	uint8 idx = 0;
  
  	Hal_ProcessPoll();

  	do {
    	if (tasksEvents[idx])  // Task is highest priority that is ready.
    	{
      		break;
    	}
  	} while (++idx < tasksCnt);

  	if (idx < tasksCnt)
  	{
    	uint16 events;
    	halIntState_t intState;

    	HAL_ENTER_CRITICAL_SECTION(intState);
    	events = tasksEvents[idx];
    	tasksEvents[idx] = 0;  // Clear the Events for this task.
    	HAL_EXIT_CRITICAL_SECTION(intState);

    	activeTaskID = idx;
    	events = (tasksArr[idx])( idx, events );
    	activeTaskID = TASK_NO_TASK;

    	HAL_ENTER_CRITICAL_SECTION(intState);
    	tasksEvents[idx] |= events;  // Add back unprocessed events to the current task.
    	HAL_EXIT_CRITICAL_SECTION(intState);
	}
	#ifdef POWER_SAVING
  	else  // Complete pass through all task events with no activity?
  	{
    	meos_pwrmgr_standby();  // Put the processor/system into sleep
  	}
	#endif
}


